package com.mars.module.workflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.mars.common.enums.ActionEnum;
import com.mars.module.workflow.entity.ActHiOpinion;
import com.mars.module.workflow.mapper.ActHiOpinionMapper;
import com.mars.module.workflow.response.ActHiOpinionResponse;
import com.mars.module.workflow.service.IActHiOpinionService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class ActHiOpinionServiceImpl implements IActHiOpinionService {


    private final ActHiOpinionMapper actHiOpinionMapper;


    @Override
    public Integer saveActHiOpinion(ActHiOpinion actHiOpinion) {
        return actHiOpinionMapper.insert(actHiOpinion);
    }

    @Override
    public List<ActHiOpinion> queryListWithoutStart(ActHiOpinion actHiOpinion) {
        QueryWrapper<ActHiOpinion> query = Wrappers.query();
        query.lambda().ne(ActHiOpinion::getType, ActionEnum.A_START.getCode());
        query.lambda().eq(StringUtils.isNotEmpty(actHiOpinion.getId()), ActHiOpinion::getId, actHiOpinion.getId());
        query.lambda().eq(StringUtils.isNotEmpty(actHiOpinion.getProcInstId()), ActHiOpinion::getProcInstId, actHiOpinion.getProcInstId());
        query.lambda().orderByAsc(ActHiOpinion::getCreateTime);
        return actHiOpinionMapper.selectList(query);
    }

    @Override
    public ActHiOpinionResponse getRelationRejectOpinion(ActHiOpinion aho) {
        QueryWrapper<ActHiOpinion> query = Wrappers.query();
        query.lambda().eq(ActHiOpinion::getProcInstId, aho.getProcInstId());
        query.lambda().eq(ActHiOpinion::getType, ActionEnum.A_REJECT.getCode());
        query.lambda().orderByDesc(ActHiOpinion::getCreateTime);
        query.last("limit 1");
        ActHiOpinion actHiOpinion = actHiOpinionMapper.selectOne(query);
        ActHiOpinionResponse response = new ActHiOpinionResponse();
        BeanUtils.copyProperties(Optional.ofNullable(actHiOpinion).orElse(new ActHiOpinion()),response);
        return response;
    }

    @Override
    public List<ActHiOpinion> removeRecallTask(List<ActHiOpinion> actHiOpinions) {
        actHiOpinions = removeRecallTask(actHiOpinions, ActionEnum.A_RECALL, Lists.newArrayList(ActionEnum.A_REJECT, ActionEnum.A_SUBMIT));
        actHiOpinions = removeRecallTask(actHiOpinions, ActionEnum.A_TRANSFER_RECALL, Lists.newArrayList(ActionEnum.A_TRANSFER));
        return actHiOpinions;
    }


    private List<ActHiOpinion> removeRecallTask(List<ActHiOpinion> actHiOpinions, ActionEnum recallAction, List<ActionEnum> recalledActions) {
        List<String> recallTaskIds = actHiOpinions.stream()
                .filter(hiOpinion -> StringUtils.equals(hiOpinion.getType(), recallAction.getCode()))
                .map(ActHiOpinion::getTaskId)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(recallTaskIds)) {
            return actHiOpinions;
        }

        List<String> toBeRemovedAction = Lists.asList(recallAction, recalledActions.toArray())
                .stream()
                .map(x -> ((ActionEnum) x).getCode())
                .collect(Collectors.toList());
        return actHiOpinions.stream()
                .filter(hiOpinion -> !(recallTaskIds.contains(hiOpinion.getTaskId()) && toBeRemovedAction.contains(hiOpinion.getType())))
                .collect(Collectors.toList());
    }
}
